package handler

import (
	"context"
	"fmt"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes/empty"
	"github.com/golang/protobuf/ptypes/wrappers"

	"kop/framework/errors"
	"kop/libs/redis"
	"kop/modules/guild/configuration"
	"kop/pb"
	"kop/pb/service"
	"kop/util/date"

	awardM "kop/modules/award/models"
	roleC "kop/modules/role/client"
)

func (h *GuildServiceHandler) DailyQuest(ctx context.Context, _ *empty.Empty, resp *service.GuildDailyQuests) error {

	var roleID, guildID = h.GetRoleID(ctx), h.GetGuildID(ctx)

	if guildID <= 0 {
		return errors.ParamError
	}

	*resp = getDailyQuestsData(guildID)
	for _, v := range resp.DailyQuests {
		_, v.Ok = v.M[roleID]
	}

	return nil
}

func (h *GuildServiceHandler) GetDailyQuestAward(ctx context.Context, req *wrappers.Int32Value, resp *pb.Award) error {

	var roleID, guildID = h.GetRoleID(ctx), h.GetGuildID(ctx)

	if guildID <= 0 {
		return errors.ParamError
	}

	var data = getDailyQuestsData(guildID)
	for _, v := range data.DailyQuests {
		if v.ID == req.Value {

			if v.M[roleID] {
				return errors.ParamError
			}

			if v.Value < v.Value2 {
				return errors.ParamError
			}

			v.M[roleID] = true
			_ = setDailyQuestsData(guildID, data)

			var role = roleC.GetRole(roleID)

			*resp = *awardM.RandAward(role, configuration.GetMission(v.ID).AwardID)
			return awardM.SendAward(role, resp)
		}
	}

	return nil
}

func getDailyQuestsData(guildID int32) service.GuildDailyQuests {

	var key = fmt.Sprintf("GuildDailyQuests%d", guildID)
	if b, err := redis.Get(key); err != nil {
		panic(err)

	} else if b != nil {

		var data service.GuildDailyQuests
		_ = proto.Unmarshal(b, &data)

		for _, v := range data.DailyQuests {
			if v.M == nil {
				v.M = make(map[int32]bool)
			}
		}

		return data

	} else {

		var data service.GuildDailyQuests
		data.DailyQuests = make([]*pb.GuildDailyQuest, 0, len(configuration.DailyQuestConfigs))

		for _, conf := range configuration.DailyQuestConfigs {
			data.DailyQuests = append(data.DailyQuests, &pb.GuildDailyQuest{
				ID:     conf.ID,
				Value:  0,
				Value2: conf.GuildMoney,
				M:      make(map[int32]bool),
			})
		}

		_ = setDailyQuestsData(guildID, data)
		return data
	}
}

func setDailyQuestsData(guildID int32, data service.GuildDailyQuests) error {

	var key = fmt.Sprintf("GuildDailyQuests%d", guildID)

	var mess, _ = proto.Marshal(&data)

	return redis.Set(key, mess, date.TodayExpire())
}

func addDailyQuestsPoints(guildID, points int32) error {

	var data = getDailyQuestsData(guildID)
	for _, v := range data.DailyQuests {
		v.Value += points
	}

	return setDailyQuestsData(guildID, data)
}
